package monet.android.mistong.com.kt_by

import android.app.Activity
import android.content.Context
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.support.annotation.ColorRes
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import android.view.View
import android.widget.TextView
import android.widget.Toast
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

class MainActivity : AppCompatActivity() {

    private val tv: TextView by bindV(R.id.tv1)
    private val tv2 :TextView by bindVWithSelector(
            R.id.tv2,
            shape = Shape(shape = "rectangle", radius = 100f, size = Size(100f,100f), color = R.color.colorAccent
            ))

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        tv.setOnClickListener {
            Toast.makeText(this, "???", Toast.LENGTH_SHORT).show()
        }

        tv2.setOnClickListener {
            Toast.makeText(this, "tv2", Toast.LENGTH_SHORT).show()
        }
    }
}

fun <V : View> Activity.bindV(id: Int)
        : ReadOnlyProperty<Activity, V> = required(id, viewFinder)

fun <V:View> Activity.bindVWithSelector(id:Int, shape:Shape):ReadOnlyProperty<Activity, V>
    = required(id, viewFinder, shape)

private val Activity.viewFinder : (Int)->View
    get() = {findViewById(it)}


private fun <T:Activity,  V : View> required(id:Int, finder: (Int) -> View): ReadOnlyProperty<T,V> {
    return BindLazy { _, _ ->
        finder(id) as V
    }
}
private fun <T:Activity, V:View> required(id:Int, finder:(Int)->View, shape:Shape):ReadOnlyProperty<T,V> {
    return BindLazy { t,_ ->
        finder(id).apply {
            val gradientDrawable = GradientDrawable().apply {
                cornerRadius = t.dp2px(shape.radius)
                setSize(t.dp2px(shape.size.width).toInt(), t.dp2px(shape.size.height).toInt())
                setColor(ContextCompat.getColor(t, shape.color))
            }
            setBackgroundDrawable(gradientDrawable)
        } as V
    }
}

class BindLazy<T,V>(private val initializer: (T, KProperty<*>) -> V):ReadOnlyProperty<T,V> {
    private object empty
    private var value: Any? = empty
    override fun getValue(thisRef: T, property: KProperty<*>): V {
        if (value == empty) {
            value = initializer(thisRef, property)
        }
        return value as V
    }

}


data class Shape(
        val shape:String,
        val radius:Float,
        val size:Size,
        @ColorRes val color: Int
)

data class Size(
        val width: Float,
        val height: Float
)

fun Context.dp2px(dp:Float):Float = dp*(
        resources.displayMetrics.density
        )+0.5f